package com.chagee.channel.server.service.third;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.chagee.channel.api.request.hik.HikCaptureReqBO;
import com.chagee.channel.api.request.hik.HikStoreCameraReqBO;
import com.chagee.channel.api.response.hik.HikAccessTokenRespBO;
import com.chagee.channel.api.response.hik.HikCaptureRespBO;
import com.chagee.channel.api.response.hik.HikEzvizAccountInfoRespBO;
import com.chagee.channel.api.response.hik.HikStoreCameraRespBO;
import com.chagee.channel.api.response.hik.HikStoreCameraRowsBO;
import com.chagee.channel.api.response.hik.HikStoreInfoRespBO;
import com.chagee.channel.api.response.hik.HikStoreInfoRowsBO;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.jackson.JsonUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 巡检全球化V1.2.4二期——海康云眸接口封装
 *
 * @author kunpeng.zhang
 * @date 2024/09/29
 */
@Service
@Slf4j
public class HikThirdService {

    @Value("${hik.clientId}")
    private String clientId;

    @Value("${hik.clientSecret}")
    private String clientSecret;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    private static final String HIK_ACCESS_TOKEN = "HikAccessToken";

    private static final Long HIK_ACCESS_TOKEN_TIME_OUT = 6 * 24 * 60 * 60 * 1000L;

    /**
     * 授权凭证获取
     *
     * @return
     */
    public HikAccessTokenRespBO getHikAccessToken() {
        HikAccessTokenRespBO respBO = new HikAccessTokenRespBO();
        String baseUrl = "https://api2.hik-cloud.com/oauth/token?client_id={}&client_secret={}&grant_type={}&scope={}";

        try {
            String clientId = this.clientId;
            String clientSecret = this.clientSecret;
            String grantType = "client_credentials";
            String scope = "app";

            String url = StrUtil.format(baseUrl, clientId, clientSecret, grantType, scope);
            log.info("Hik_url: {}", url);

            String hikAccessToken = redisTemplate.opsForValue().get(HIK_ACCESS_TOKEN);

            log.info("redis_hikAccessToken: {}", hikAccessToken);

            // 验证token是否有效
            boolean isEfficientFlag = this.verifyToken(hikAccessToken);
            log.info("Hik_efficientFlag: {}", isEfficientFlag);
            if (Boolean.FALSE.equals(isEfficientFlag) || StrUtil.isBlank(hikAccessToken)) {
                // 发送请求并获取响应
                HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
                connection.setRequestMethod("POST");

                // 获取响应代码
                int responseCode = connection.getResponseCode();
                log.info("Hik_responseCode: {}", responseCode);

                // 读取响应内容
                if (responseCode == HttpURLConnection.HTTP_OK || responseCode == 0) {
                    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String inputLine;
                    StringBuilder response = new StringBuilder();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();
                    log.info("Hik_response: {}", response.toString());
                    if (StrUtil.isNotBlank(response.toString())) {
                        respBO = JsonUtil.parse(response.toString(), HikAccessTokenRespBO.class);
                        log.info("Hik_respBO: {}", JSONUtil.toJsonStr(respBO));

                        // 更新redis
                        redisTemplate.opsForValue().set(HIK_ACCESS_TOKEN, respBO.getAccessToken(), HIK_ACCESS_TOKEN_TIME_OUT, TimeUnit.MILLISECONDS);
                        return respBO;
                    }
                } else {
                    log.info("Hik_error: {}", connection.getResponseMessage());
                }
            } else {
                respBO.setAccessToken(hikAccessToken);
            }
        } catch (Exception e) {
            log.error("Hik_exception: ", e);
        }
        return respBO;
    }

    /**
     * 验证token是否生效
     *
     * @param hikAccessToken
     * @return
     */
    public Boolean verifyToken(String hikAccessToken) {
        if (StrUtil.isBlank(hikAccessToken)) {
            return Boolean.FALSE;
        }

        String url = "https://api2.hik-cloud.com/v1/ezviz/account/info";

        try {
            // 发送请求并获取响应
            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Authorization", "Bearer " + hikAccessToken);

            // 获取响应代码
            int responseCode = connection.getResponseCode();
            log.info("Hik_verifyToken_responseCode: {}", responseCode);

            // 读取响应内容
            if (responseCode == HttpURLConnection.HTTP_OK || responseCode == 0) {
                return Boolean.TRUE;
            } else {
                return Boolean.FALSE;
            }
        } catch (Exception e) {
            log.error("Hik_verifyToken_exception: ", e);
        }

        return Boolean.FALSE;
    }

    /**
     * 获取WEB视频控件token
     *
     * @return
     */
    public HikAccessTokenRespBO getVideoToken() {
        HikAccessTokenRespBO respBO = new HikAccessTokenRespBO();
        String url = "https://api2.hik-cloud.com/v1/auth/open/getVideoToken";

        // 获取access_token
        HikAccessTokenRespBO hikAccessTokenRespBO = this.getHikAccessToken();
        if (ObjectUtil.isNotNull(hikAccessTokenRespBO) && StrUtil.isNotBlank(hikAccessTokenRespBO.getAccessToken())) {
            String hikAccessToken = hikAccessTokenRespBO.getAccessToken();

            try {
                // 发送请求并获取响应
                HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Authorization", "Bearer " + hikAccessToken);

                // 获取响应代码
                int responseCode = connection.getResponseCode();
                log.info("Hik_getVideoToken_responseCode: {}", responseCode);

                // 读取响应内容
                if (responseCode == HttpURLConnection.HTTP_OK || responseCode == 0) {
                    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String inputLine;
                    StringBuilder response = new StringBuilder();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();
                    log.info("Hik_getVideoToken_response: {}", response.toString());
                    if (StrUtil.isNotBlank(response.toString())) {
                        respBO = JsonUtil.parse(response.toString(), HikAccessTokenRespBO.class);
                        log.info("Hik_getVideoToken_respBO: {}", JSONUtil.toJsonStr(respBO));
                        return respBO;
                    }
                } else {
                    log.info("Hik_getVideoToken_error: {}", connection.getResponseMessage());
                }
            } catch (Exception e) {
                log.error("Hik_getVideoToken_exception: ", e);
            }
        } else {
            // 获取access_token失败
            log.info("Hik_getVideoToken_error: {}", "<取流认证token获取>获取access_token失败");
        }
        return respBO;
    }

    /**
     * 取流认证token获取
     *
     * @return
     */
    public HikEzvizAccountInfoRespBO getEzvizAccountInfo() {
        HikEzvizAccountInfoRespBO respBO = new HikEzvizAccountInfoRespBO();
        String url = "https://api2.hik-cloud.com/v1/ezviz/account/info";

        // 获取access_token
        HikAccessTokenRespBO hikAccessTokenRespBO = this.getHikAccessToken();
        if (ObjectUtil.isNotNull(hikAccessTokenRespBO) && StrUtil.isNotBlank(hikAccessTokenRespBO.getAccessToken())) {
            String hikAccessToken = hikAccessTokenRespBO.getAccessToken();

            try {
                // 发送请求并获取响应
                HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
                connection.setRequestMethod("GET");
                connection.setRequestProperty("Authorization", "Bearer " + hikAccessToken);

                // 获取响应代码
                int responseCode = connection.getResponseCode();
                log.info("Hik_getEzvizAccountInfo_responseCode: {}", responseCode);

                // 读取响应内容
                if (responseCode == HttpURLConnection.HTTP_OK || responseCode == 0) {
                    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String inputLine;
                    StringBuilder response = new StringBuilder();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();
                    log.info("Hik_getEzvizAccountInfo_response: {}", response.toString());
                    if (StrUtil.isNotBlank(response.toString())) {
                        JSONObject jsonObject = JSONUtil.parseObj(response.toString());
                        JSONObject data = (JSONObject) jsonObject.get("data");
                        log.info("Hik_getEzvizAccountInfo_data: {}", JSONUtil.toJsonStr(data));
                        respBO = JsonUtil.parse(data.toString(), HikEzvizAccountInfoRespBO.class);
                        log.info("Hik_getEzvizAccountInfo_respBO: {}", JSONUtil.toJsonStr(respBO));
                        return respBO;
                    }
                } else {
                    log.info("Hik_getEzvizAccountInfo_error: {}", connection.getResponseMessage());
                }
            } catch (Exception e) {
                log.error("Hik_getEzvizAccountInfo_exception: ", e);
            }
        } else {
            // 获取access_token失败
            log.info("Hik_getEzvizAccountInfo_error: {}", "<取流认证token获取>获取access_token失败");
        }
        return respBO;
    }

    /**
     * 通过门店编号查询设备通道列表
     *
     * @param reqBO
     * @return
     */
    public HikStoreCameraRespBO getStoreCameraList(HikStoreCameraReqBO reqBO) {
        log.info("getStoreCameraList_reqBO: {}", JSONUtil.toJsonStr(reqBO));
        HikStoreCameraRespBO respBO = new HikStoreCameraRespBO();
        String baseUrl = "https://api2.hik-cloud.com/v1/customization/store/cameraList?storeNo={}&pageNo={}&pageSize={}";

        String storeNo = reqBO.getStoreNo();
        Integer pageNo = reqBO.getPageNo();
        Integer pageSize = reqBO.getPageSize();

        String url = StrUtil.format(baseUrl, storeNo, pageNo, pageSize);
        log.info("Hik_getStoreCameraList_url: {}", url);

        // 获取access_token
        HikAccessTokenRespBO hikAccessTokenRespBO = this.getHikAccessToken();
        if (ObjectUtil.isNotNull(hikAccessTokenRespBO) && StrUtil.isNotBlank(hikAccessTokenRespBO.getAccessToken())) {
            String hikAccessToken = hikAccessTokenRespBO.getAccessToken();

            try {
                // 发送请求并获取响应
                HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
                connection.setRequestMethod("GET");
                connection.setRequestProperty("Authorization", "Bearer " + hikAccessToken);

                // 获取响应代码
                int responseCode = connection.getResponseCode();
                log.info("Hik_getStoreCameraList_responseCode: {}", responseCode);

                // 读取响应内容
                if (responseCode == HttpURLConnection.HTTP_OK || responseCode == 0) {
                    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String inputLine;
                    StringBuilder response = new StringBuilder();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();
                    log.info("Hik_getStoreCameraList_response: {}", response.toString());
                    if (StrUtil.isNotBlank(response.toString())) {
                        JSONObject jsonObject = JSONUtil.parseObj(response.toString());
                        JSONObject data = (JSONObject) jsonObject.get("data");
                        log.info("Hik_getStoreCameraList_data: {}", JSONUtil.toJsonStr(data));
                        respBO = JsonUtil.parse(data.toString(), HikStoreCameraRespBO.class);
                        JSONArray rowsArray = data.getJSONArray("rows");
                        log.info("Hik_getStoreCameraList_rowsArray: {}", JSONUtil.toJsonStr(rowsArray));

                        List<HikStoreCameraRowsBO> rows = new ArrayList<>();
                        for (int i = 0; i < rowsArray.size(); i++) {
                            HikStoreCameraRowsBO rowsBO = JsonUtil.parse(rowsArray.get(i).toString(), HikStoreCameraRowsBO.class);
                            rows.add(rowsBO);
                        }

                        log.info("Hik_getStoreCameraList_rows: {}", JSONUtil.toJsonStr(rows));
                        respBO.setRows(rows);
                        log.info("Hik_getStoreCameraList_respBO: {}", JSONUtil.toJsonStr(respBO));
                        return respBO;
                    }
                } else {
                    log.info("Hik_getStoreCameraList_error: {}", connection.getResponseMessage());
                }
            } catch (Exception e) {
                log.error("Hik_getStoreCameraList_exception: ", e);
            }
        } else {
            // 获取access_token失败
            log.info("Hik_getStoreCameraList_error: {}", "<取流认证token获取>获取access_token失败");
        }
        return respBO;
    }

    /**
     * 远程抓图
     *
     * @param reqBO
     * @return
     */
    public HikCaptureRespBO basicCapture(HikCaptureReqBO reqBO) {
        log.info("basicCapture_reqBO: {}", JSONUtil.toJsonStr(reqBO));
        String baseUrl = "https://api2.hik-cloud.com/api/v1/open/basic/channels/actions/capture?deviceSerial={}&channelNo={}&quality={}";
        HikCaptureRespBO respBO = new HikCaptureRespBO();

        String deviceSerial = reqBO.getDeviceSerial();
        Integer channelNo = reqBO.getChannelNo();
        Integer quality = reqBO.getQuality();

        String url = StrUtil.format(baseUrl, deviceSerial, channelNo, quality);
        log.info("Hik_basicCapture_url: {}", url);

        // 获取access_token
        HikAccessTokenRespBO hikAccessTokenRespBO = this.getHikAccessToken();
        if (ObjectUtil.isNotNull(hikAccessTokenRespBO) && StrUtil.isNotBlank(hikAccessTokenRespBO.getAccessToken())) {
            String hikAccessToken = hikAccessTokenRespBO.getAccessToken();

            try {
                // 发送请求并获取响应
                HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Content-Type", "application/json");
                connection.setRequestProperty("Authorization", "Bearer " + hikAccessToken);

                // 获取响应代码
                int responseCode = connection.getResponseCode();
                log.info("Hik_basicCapture_responseCode: {}", responseCode);

                // 读取响应内容
                if (responseCode == HttpURLConnection.HTTP_OK || responseCode == 0) {
                    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String inputLine;
                    StringBuilder response = new StringBuilder();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();
                    log.info("Hik_basicCapture_response: {}", response.toString());
                    if (StrUtil.isNotBlank(response.toString())) {
                        JSONObject jsonObject = JSONUtil.parseObj(response.toString());
                        JSONObject data = (JSONObject) jsonObject.get("data");
                        log.info("Hik_basicCapture_data: {}", JSONUtil.toJsonStr(data));
                        respBO = JsonUtil.parse(data.toString(), HikCaptureRespBO.class);
                        log.info("Hik_basicCapture_respBO: {}", JSONUtil.toJsonStr(respBO));
                        return respBO;
                    }
                } else {
                    log.info("Hik_basicCapture_error: {}", connection.getResponseMessage());
                }
            } catch (Exception e) {
                log.error("Hik_basicCapture_exception: ", e);
            }
        } else {
            // 获取access_token失败
            log.info("Hik_basicCapture_error: {}", "<取流认证token获取>获取access_token失败");
        }
        return respBO;
    }

    /**
     * 设备抓图
     *
     * @param reqBO
     * @return
     */
    public HikCaptureRespBO customizationCapture(HikCaptureReqBO reqBO) {
        log.info("customizationCapture_reqBO: {}", JSONUtil.toJsonStr(reqBO));
        String baseUrl = "https://api2.hik-cloud.com/v1/customization/capture?deviceSerial={}&channelNo={}&quality={}";
        HikCaptureRespBO respBO = new HikCaptureRespBO();

        String deviceSerial = reqBO.getDeviceSerial();
        Integer channelNo = reqBO.getChannelNo();
        Integer quality = reqBO.getQuality();

        String url = StrUtil.format(baseUrl, deviceSerial, channelNo, quality);
        log.info("Hik_customizationCapture_url: {}", url);

        // 获取access_token
        HikAccessTokenRespBO hikAccessTokenRespBO = this.getHikAccessToken();
        if (ObjectUtil.isNotNull(hikAccessTokenRespBO) && StrUtil.isNotBlank(hikAccessTokenRespBO.getAccessToken())) {
            String hikAccessToken = hikAccessTokenRespBO.getAccessToken();

            try {
                // 发送请求并获取响应
                HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                connection.setRequestProperty("Authorization", "Bearer " + hikAccessToken);

                // 获取响应代码
                int responseCode = connection.getResponseCode();
                log.info("Hik_customizationCapture_responseCode: {}", responseCode);

                // 读取响应内容
                if (responseCode == HttpURLConnection.HTTP_OK || responseCode == 0) {
                    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String inputLine;
                    StringBuilder response = new StringBuilder();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();
                    log.info("Hik_customizationCapture_response: {}", response.toString());
                    if (StrUtil.isNotBlank(response.toString())) {
                        JSONObject jsonObject = JSONUtil.parseObj(response.toString());
                        JSONObject data = (JSONObject) jsonObject.get("data");
                        log.info("Hik_customizationCapture_data: {}", JSONUtil.toJsonStr(data));
                        respBO = JsonUtil.parse(data.toString(), HikCaptureRespBO.class);
                        log.info("Hik_customizationCapture_respBO: {}", JSONUtil.toJsonStr(respBO));
                        return respBO;
                    }
                } else {
                    log.info("Hik_customizationCapture_error: {}", connection.getResponseMessage());
                }
            } catch (Exception e) {
                log.error("Hik_customizationCapture_exception: ", e);
            }
        } else {
            // 获取access_token失败
            log.info("Hik_customizationCapture_error: {}", "<取流认证token获取>获取access_token失败");
        }
        return respBO;
    }

    /**
     * 获取门店列表
     *
     * @param reqBO
     * @return
     */
    public HikStoreInfoRespBO getStoreInfoPage(HikStoreCameraReqBO reqBO) {
        log.info("getStoreCameraList_reqBO: {}", JSONUtil.toJsonStr(reqBO));
        HikStoreInfoRespBO respBO = new HikStoreInfoRespBO();
        String baseUrl = "https://api2.hik-cloud.com/v1/customization/storeInfo?pageNo={}&pageSize={}&storeNo={}";

        String storeNo = reqBO.getStoreNo();
        Integer pageNo = reqBO.getPageNo();
        Integer pageSize = reqBO.getPageSize();

        String url = StrUtil.format(baseUrl, pageNo, pageSize, storeNo);
        log.info("Hik_getStoreInfoPage_url: {}", url);

        // 获取access_token
        HikAccessTokenRespBO hikAccessTokenRespBO = this.getHikAccessToken();
        if (ObjectUtil.isNotNull(hikAccessTokenRespBO) && StrUtil.isNotBlank(hikAccessTokenRespBO.getAccessToken())) {
            String hikAccessToken = hikAccessTokenRespBO.getAccessToken();

            try {
                // 发送请求并获取响应
                HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
                connection.setRequestMethod("GET");
                connection.setRequestProperty("Authorization", "Bearer " + hikAccessToken);

                // 获取响应代码
                int responseCode = connection.getResponseCode();
                log.info("Hik_getStoreInfoPage_responseCode: {}", responseCode);

                // 读取响应内容
                if (responseCode == HttpURLConnection.HTTP_OK || responseCode == 0) {
                    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String inputLine;
                    StringBuilder response = new StringBuilder();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();
                    log.info("Hik_getStoreInfoPage_response: {}", response.toString());
                    if (StrUtil.isNotBlank(response.toString())) {
                        JSONObject jsonObject = JSONUtil.parseObj(response.toString());
                        JSONObject data = (JSONObject) jsonObject.get("data");
                        log.info("Hik_getStoreInfoPage_data: {}", JSONUtil.toJsonStr(data));
                        respBO = JsonUtil.parse(data.toString(), HikStoreInfoRespBO.class);
                        JSONArray rowsArray = data.getJSONArray("rows");
                        log.info("Hik_getStoreInfoPage_rowsArray: {}", JSONUtil.toJsonStr(rowsArray));

                        List<HikStoreInfoRowsBO> rows = new ArrayList<>();
                        for (int i = 0; i < rowsArray.size(); i++) {
                            HikStoreInfoRowsBO rowsBO = JsonUtil.parse(rowsArray.get(i).toString(), HikStoreInfoRowsBO.class);
                            rows.add(rowsBO);
                        }

                        log.info("Hik_getStoreInfoPage_rows: {}", JSONUtil.toJsonStr(rows));
                        respBO.setRows(rows);
                        log.info("Hik_getStoreInfoPage_respBO: {}", JSONUtil.toJsonStr(respBO));
                        return respBO;
                    }
                } else {
                    log.info("Hik_getStoreInfoPage_error: {}", connection.getResponseMessage());
                }
            } catch (Exception e) {
                log.error("Hik_getStoreInfoPage_exception: ", e);
            }
        } else {
            // 获取access_token失败
            log.info("Hik_getStoreInfoPage_error: {}", "<取流认证token获取>获取access_token失败");
        }
        return respBO;
    }
}